--- @param extension Package
--- @param HY HY_Utility
--- @param U Utility
return function(extension, HY, U)
    local hy_yorigami_shion = General:new(extension, "hy_yorigami_shion", "chi_k", 4, 4, General.Female)
    local unfortunate_poverty = fk.CreateSkill {
        name = "unfortunate_poverty",
    }
    unfortunate_poverty:addEffect(fk.Damage, {
        anim_type = "negative",
        can_trigger = function(self, event, target, player, data)
            if data.card == nil then
                return false
            end
            return player:hasSkill(unfortunate_poverty.name) and target and target ~= player and data.card.trueName == "slash" and player:inMyAttackRange(target)
        end,
        on_cost = function(self, event, target, player, data)
            return player.room:askToSkillInvoke(player, {
                skill_name = unfortunate_poverty.name,
                prompt = "unfortunate_poverty_prompt::" .. target.id
            })
        end,
        on_use = function(self, event, target, player)
            local room = player.room
            if #table.filter(target.player_cards[Player.Hand], function(id)
                    return not target:prohibitDiscard(Fk:getCardById(id))
                end) < 2 then
                room:loseHp(target, 1, unfortunate_poverty.name)
            else
                local cardIds = room:askToDiscard(target, {
                    min_num = 2,
                    max_num = 2,
                    skill_name = unfortunate_poverty.name,
                    prompt = "unfortunate_poverty_prompt_choice"
                })
                if #cardIds < 2 then
                    room:loseHp(target, 1, unfortunate_poverty.name)
                end
            end
        end
    })
    Fk:addPoxiMethod({
        name = "extremely_wicked_fail_box",
        card_filter = function(to_select, selected, data)
            return #selected < 4
        end,
        feasible = function(selected, data)
            return #selected == 4
        end,
        prompt = "extremely_wicked_fail_prompt",
        default_choice = function(data)
            local cardIds = {}
            for _, d in ipairs(data) do
                table.insertTable(cardIds, d[2])
            end
            return table.random(cardIds, 4)
        end,
        post_select = function(selected, data)
            return selected
        end,
    })
    local extremely_wicked = fk.CreateSkill {
        name = "extremely_wicked",
        tags = {
            Skill.Quest
        }
    }
    extremely_wicked:addEffect(fk.TurnEnd, {
        anim_type = "support",
        can_trigger = function(self, event, target, player)
            if player:getQuestSkillState("extremely_wicked") then
                return false
            end
            return player:hasSkill(extremely_wicked.name) and player:isKongcheng() and player.room.current == player
        end,
        on_cost = Util.TrueFunc,
        on_use = function(self, event, target, player)
            if player:isWounded() then
                player.room:recover({
                    who = player,
                    num = 1,
                    recoverBy = player,
                    skillName = extremely_wicked.name,
                })
            end
        end
    })
    extremely_wicked:addEffect(fk.EventPhaseStart, {
        can_trigger = function(self, event, target, player)
            if player:getQuestSkillState("extremely_wicked") then
                return false
            end
            for _, t in ipairs(player.room:getOtherPlayers(player)) do
                if t.hp > player.hp then
                    return false
                end
            end
            return player:hasSkill("extremely_wicked") and player.room:getBanner("RoundCount") > 1 and player.room.current == player and player.phase == Player.Start
        end,
        on_cost = Util.TrueFunc,
        on_use = function(self, event, target, player)
            player.room:notifySkillInvoked(player, "extremely_wicked")
            player.room:updateQuestSkillState(player, "extremely_wicked")
            player.room:handleAddLoseSkills(player, "-unfortunate_poverty|transfer_disaster", nil,
                true, false)
        end
    })
    extremely_wicked:addEffect(fk.EnterDying, {
        anim_type = "negative",
        can_trigger = function(self, event, target, player)
            if player:getQuestSkillState("extremely_wicked") then
                return false
            end
            return player:hasSkill("extremely_wicked") and target == player
        end,
        on_cost = Util.TrueFunc,
        on_use = function(self, event, target, player)
            player.room:notifySkillInvoked(player, "extremely_wicked", "negative")
            player.room:updateQuestSkillState(player, "extremely_wicked", true)
            local room = player.room
            local hp = player.hp
            if player:isWounded() then
                room:recover({
                    who = player,
                    num = 1 - hp,
                    recoverBy = player,
                    skillName = extremely_wicked.name,
                })
            end
            local boards = {}
            for _, t in ipairs(room.alive_players) do
                table.insertTable(boards, t.player_cards[Player.Equip])
                table.insertTable(boards, t.player_cards[Player.Judge])
            end
            local hands = table.filter(target.player_cards[Player.Hand], function(id)
                return not player:prohibitDiscard(Fk:getCardById(id))
            end)
            local move = {}
            if #boards + #hands <= 4 then
                for _, t in ipairs(room:getAlivePlayers(true)) do
                    local discards = table.filter(table.connect(boards, hands), function(id, _, _)
                        return table.contains(t.player_cards[Player.Hand], id) or
                            table.contains(t.player_cards[Player.Equip], id) or
                            table.contains(t.player_cards[Player.Judge], id)
                    end)
                    if #discards > 0 then
                        table.insert(move, {
                            ids = discards,
                            from = t,
                            toArea = Card.DiscardPile,
                            moveReason = fk.ReasonDiscard,
                            proposer = player,
                            skillName = extremely_wicked.name,
                        })
                    end
                end
            else
                local data = {}
                if #boards > 0 then
                    table.insert(data, { "extremely_wicked_board", boards })
                end
                if #hands > 0 then
                    table.insert(data, { "extremely_wicked_hand", hands })
                end
                local result = room:askToPoxi(player, {
                    poxi_type = "extremely_wicked_fail_box",
                    data = data
                })
                for _, t in ipairs(room:getAlivePlayers(true)) do
                    local discards = table.filter(result, function(id, _, _)
                        return table.contains(t.player_cards[Player.Hand], id) or
                            table.contains(t.player_cards[Player.Equip], id) or
                            table.contains(t.player_cards[Player.Judge], id)
                    end)
                    if #discards > 0 then
                        table.insert(move, {
                            ids = discards,
                            from = t,
                            toArea = Card.DiscardPile,
                            moveReason = fk.ReasonDiscard,
                            proposer = player,
                            skillName = extremely_wicked.name,
                        })
                    end
                end
            end
            room:moveCards(table.unpack(move))
        end
    })
    local transfer_disaster = fk.CreateSkill {
        name = "transfer_disaster",
    }
    transfer_disaster:addEffect("active", {
        anim_type = "offensive",
        can_use = function(self, player)
            local players = Fk:currentRoom().alive_players
            for _, p1 in ipairs(players) do
                for _, p2 in ipairs(players) do
                    if p1 == p2 then
                        break
                    end
                    if p1:getHandcardNum() ~= p2:getHandcardNum() then
                        return player:hasSkill(transfer_disaster.name) and player:usedSkillTimes(transfer_disaster.name, Player.HistoryTurn) == 0
                    end
                end
            end
            return false
        end,
        target_filter = function(self, player, to_select, selected, selected_cards)
            if #selected == 0 then
                return true
            end
            return #selected < 2 and selected[1]:getHandcardNum() ~= to_select:getHandcardNum()
        end,
        target_num = 2,
        card_filter = Util.FalseFunc,
        prompt = function(self, player, selected_cards, selected_targets)
            return "transfer_disaster_prompt"
        end,
        target_tip = function(self, player, to_select, selected, selected_cards, card, selectable, extra_data)
            if #selected == 2 then
                if #selected[1]:getCardIds("h") > #selected[2]:getCardIds("h") then
                    if to_select == selected[1] then
                        return "transfer_disaster_loseHp"
                    elseif to_select == selected[2] then
                        return "transfer_disaster_recover"
                    end
                else
                    if to_select == selected[2] then
                        return "transfer_disaster_loseHp"
                    elseif to_select == selected[1] then
                        return "transfer_disaster_recover"
                    end
                end
            end
        end,
        on_use = function(self, room, skillUseEvent)
            local target1 = skillUseEvent.tos[1]
            local target2 = skillUseEvent.tos[2]
            if target1:getHandcardNum() > target2:getHandcardNum() then
                if target2:isWounded() then
                    room:recover({
                        who = target2,
                        num = 1,
                        recoverBy = skillUseEvent.from,
                        skillName = transfer_disaster.name,
                    })
                end
                room:loseHp(target1, 1, transfer_disaster.name)
            else
                if target1:isWounded() then
                    room:recover({
                        who = target1,
                        num = 1,
                        recoverBy = skillUseEvent.from,
                        skillName = transfer_disaster.name,
                    })
                end
                room:loseHp(target2, 1, transfer_disaster.name)
            end
        end
    })
    extension:loadSkillSkels { unfortunate_poverty, extremely_wicked, transfer_disaster }
    hy_yorigami_shion:addSkills { "unfortunate_poverty", "extremely_wicked" }
    hy_yorigami_shion:addRelatedSkill("transfer_disaster")
    Fk:loadTranslationTable {
        ["hy_yorigami_shion"] = "依神紫苑",
        ["#hy_yorigami_shion"] = "如影随形的阴郁",
        ["illustrator:hy_yorigami_shion"] = "りひと",
        ["designer:hy_yorigami_shion"] = "黑曜人形",
        ["cv:hy_yorigami_shion"] = "",

        ["unfortunate_poverty"] = "贫乏",
        [":unfortunate_poverty"] = "你攻击范围内的角色使用【杀】造成伤害后，你可以令其选择一项：1.失去1点体力；2.弃置两张手牌。",
        ["unfortunate_poverty_prompt"] = "贫乏：你可以令%dest弃置手牌或失去体力",
        ["unfortunate_poverty_prompt_choice"] = "贫乏：弃置两张手牌，或失去一点体力",

        ["extremely_wicked"] = "极恶",
        [":extremely_wicked"] = "使命技，结束阶段，若你没有手牌，你回复1点体力。<br>&nbsp;&nbsp;&nbsp;&nbsp;成功：准备阶段，若你为场上体力最多的角色且此轮不是首轮，你失去“贫乏”，获得“<a href = ':transfer_disaster'>免祸</a>”。<br>&nbsp;&nbsp;&nbsp;&nbsp;失败：当你进入濒死状态时，你将体力回复至1点，然后弃置你的手牌与场上的牌共四张（不足则全弃）。",
        ["#extremely_wicked_trigger"] = "极恶",
        ["#extremely_wicked_success"] = "极恶",
        ["#extremely_wicked_fail"] = "极恶",
        ["extremely_wicked_fail_box"] = "极恶",
        ["extremely_wicked_fail_prompt"] = "极恶:弃置手牌与场上共四张牌",
        ["extremely_wicked_board"] = "场上",
        ["extremely_wicked_hand"] = "手牌",

        ["transfer_disaster"] = "免祸",
        [":transfer_disaster"] = "出牌阶段限一次，你可以选择手牌数不等的两名角色，令其中手牌较多的角色失去1点体力，另一名角色回复1点体力。",
        ["transfer_disaster_prompt"] = "免祸：手牌数较多的角色失去体力，较少的回复体力",
        ["transfer_disaster_loseHp"] = "失去体力",
        ["transfer_disaster_recover"] = "回复体力",
    }
end
